package com.example.demo.service;

import com.alibaba.fastjson.JSON;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

@Component
public class RedisService {

    @Autowired
    private RedisTemplate redisTemplate;

    public boolean hasKey(String key) {
        if (key == null || key.trim().isEmpty()) {
            return false;
        }
        return this.redisTemplate.hasKey(key).booleanValue();
    }

    public void expire(String key, Long expireTime, TimeUnit timeUnit) {
        if (key == null || key.trim().isEmpty()) {
            return;
        }
        this.redisTemplate.expire(key, expireTime.longValue(), timeUnit);
    }

    public boolean set(String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = this.redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public boolean set(String key, Object value, Long expireTime, TimeUnit timeUnit) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = this.redisTemplate.opsForValue();
            operations.set(key, value);
            this.redisTemplate.expire(key, expireTime.longValue(), timeUnit);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public void remove(String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    public void removePattern(String pattern) {
        Set<Serializable> keys = this.redisTemplate.keys(pattern);
        if (keys.size() > 0) {
            this.redisTemplate.delete(keys);
        }
    }

    public void remove(String key) {
        if (exists(key)) {
            this.redisTemplate.delete(key);
        }
    }

    public boolean exists(String key) {
        return this.redisTemplate.hasKey(key).booleanValue();
    }

    public Object get(String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = this.redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }

    public void hmSet(String key, Object hashKey, Object value) {
        HashOperations<String, Object, Object> hash = this.redisTemplate.opsForHash();
        hash.put(key, hashKey, value);
    }

    public Object hmGet(String key, Object hashKey) {
        HashOperations<String, Object, Object> hash = this.redisTemplate.opsForHash();
        return hash.get(key, hashKey);
    }

    public <T> Long listRemove(String key, long count, T value) {
        ListOperations<String, T> list = this.redisTemplate.opsForList();
        return list.remove(key, count, value);
    }

    public Long listSize(String key) {
        ListOperations<String, Object> list = this.redisTemplate.opsForList();
        return list.size(key);
    }

    public <T> void listPush(String k, T v) {
        ListOperations<String, T> list = this.redisTemplate.opsForList();
        list.rightPush(k, v);
    }

    public <T> List<T> listRange(String key, long start, long end) {
        ListOperations<String, T> list = this.redisTemplate.opsForList();
        return list.range(key, start, end);
    }

    public <T> void listPush(String k, List<T> lists) {
        if (lists == null || lists.isEmpty()) {
            return;
        }
        ListOperations<String, T> list = this.redisTemplate.opsForList();
        list.rightPushAll(k, lists);
    }

    public <T> void leftListPush(String k, List<T> lists) {
        if (lists == null || lists.isEmpty()) {
            return;
        }
        ListOperations<String, T> list = this.redisTemplate.opsForList();
        list.leftPushAll(k, lists);
    }

    public void listPush(String k, List<?> lists, Long expireTime, TimeUnit timeUnit) {
        if (lists == null || lists.isEmpty()) {
            return;
        }
        ListOperations<String, Object> list = this.redisTemplate.opsForList();
        list.rightPushAll(k, new Object[]{lists});
        this.redisTemplate.expire(k, expireTime.longValue(), timeUnit);
    }

    public void leftListPush(String k, List<?> lists, Long expireTime, TimeUnit timeUnit) {
        if (lists == null || lists.isEmpty()) {
            return;
        }
        ListOperations<String, Object> list = this.redisTemplate.opsForList();
        list.leftPushAll(k, new Object[]{lists});
        this.redisTemplate.expire(k, expireTime.longValue(), timeUnit);
    }

    public <T> List<T> listAll(String key) {
        ListOperations<String, T> list = this.redisTemplate.opsForList();
        return list.range(key, 0L, list.size(key).longValue());
    }

    public void expireListPush(String k, List<?> lists, Long expireTime, TimeUnit timeUnit) {
        if (lists == null || lists.isEmpty()) {
            return;
        }
        String listJson = JSON.toJSONString(lists);
        set(k, listJson, expireTime, timeUnit);
    }

    public List<Object> expireListAll(String key) {
        ValueOperations<Serializable, Object> vp = this.redisTemplate.opsForValue();
        String listJson = (String) vp.get(key);
        return JSON.parseArray(listJson, Object.class);
    }

    public <T> List<T> expireListAll(String key, Class<T> clazz) {
        ValueOperations<Serializable, Object> vp = this.redisTemplate.opsForValue();
        String listJson = (String) vp.get(key);
        return JSON.parseArray(listJson, clazz);
    }

    public void add(String key, Object value) {
        SetOperations<String, Object> set = this.redisTemplate.opsForSet();
        set.add(key, new Object[]{value});
    }

    public Set<Object> setMembers(String key) {
        SetOperations<String, Object> set = this.redisTemplate.opsForSet();
        return set.members(key);
    }

    public void zAdd(String key, Object value, double scoure) {
        ZSetOperations<String, Object> zset = this.redisTemplate.opsForZSet();
        zset.add(key, value, scoure);
    }

    public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
        ZSetOperations<String, Object> zset = this.redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }

    public boolean setIfAbsent(String key, Object value) {
        return this.redisTemplate.opsForValue().setIfAbsent(key, value).booleanValue();
    }

    public int increment(String key, int delta) {
        return this.redisTemplate.opsForValue().increment(key, delta).intValue();
    }
}
